package translator.ui;

import java.util.Collection;
import java.util.LinkedHashSet;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import translator.core.Controller;
import translator.messages.Messages;
import translator.provider.SeznamTranslator;

public class MainScreen {

    private static final int WIDTH = 600;
    private static final int HEIGHT = 400;
    private static final int MARGIN = 5;
    private static final int BUTTON_HEIGHT = 25;
    private static final int BUTTON_WIDTH = 100;

    private static final String TITLE = Messages.getString("mainscreen.title");
    private static final String SWITCH = Messages.getString("mainscreen.switch");
    private static final String FROM = Messages.getString("mainscreen.from");
    private static final String TO = Messages.getString("mainscreen.to");
    private static final String SPACE = "  ";

    private Shell shell;
    private Controller controller;

    private Table table;

    private String word;
    private String[] translations;

    public MainScreen(Display display) {
        shell = new Shell(display);
        controller = new Controller(new SeznamTranslator());
        createContent();
    }

    private void createContent() {

        shell.setText(TITLE);
        shell.setSize(WIDTH + 6, HEIGHT + 28); //correction
        shell.setImage(new Image(null, getClass().getClassLoader().getResourceAsStream("translator/images/book.png")));

        //layout
        GridLayout gridLayout = new GridLayout(2, false);
        gridLayout.verticalSpacing = MARGIN;
        gridLayout.horizontalSpacing = MARGIN;
        shell.setLayout(gridLayout);

        createInsertText(shell);

        Button switchButt = new Button(shell, SWT.NONE);
        GridData gridData = new GridData();
        gridData.heightHint = BUTTON_HEIGHT + 8;
        gridData.widthHint = BUTTON_WIDTH;
        switchButt.setLayoutData(gridData);
        switchButt.setText(SWITCH);
        switchButt.addListener(SWT.Selection, new Listener() {

            @Override
            public void handleEvent(Event event) {
                switchLanguages();
            }
        });

        //table
        table = new Table(shell, SWT.MULTI | SWT.BORDER | SWT.FULL_SELECTION | SWT.VIRTUAL);
        gridData = new GridData(GridData.FILL_BOTH);
        gridData.horizontalSpan = 2;
        table.setLayoutData(gridData);
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        
        table.addListener(SWT.Resize, new Listener() {
            @Override
            public void handleEvent(Event event) {
                refreshColumnWidth();
            }
        });

        String[] titles = {FROM, TO};
        for (int i = 0; i < titles.length; i++) {
            TableColumn column = new TableColumn(table, SWT.NONE);
            column.setText(titles[i]);
        }
        refreshColumnWidth();
        table.addListener(SWT.SetData, new Listener() {

            @Override
            public void handleEvent(Event event) {
                TableItem item = (TableItem) event.item;
                int index = table.indexOf(item);
                item.setText(0, word);
                item.setText(1, translations[index]);

//                if(index + 1 == translations.length) {//last to update
//                    refreshColumnWidth();
//                }
            }
        });

        setTexts();

    }

    private Text createInsertText(final Shell shell) {
        final Text text = new Text(shell, SWT.BORDER);
        text.setFont(new Font(shell.getDisplay(), "Times New Roman", 16, SWT.NORMAL));
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.heightHint = BUTTON_HEIGHT;
        text.setLayoutData(gridData);

        final Runnable selectText = new Runnable() {
            @Override
            public void run() {
                text.setSelection(0, text.getText().length());
            }
        };

        text.addListener(SWT.KeyDown, new Listener() {
            @Override
            public void handleEvent(Event event) {
                if(event.keyCode == SWT.CR) {
                    text.setEditable(false);
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            shell.getDisplay().asyncExec(new Runnable() {
                                @Override
                                public void run() {
                                    translate(text.getText());
                                    text.setEditable(true);
                                    selectText.run();
                                }
                            });
                        }
                    }).start();
                }
            }
        });
        text.addListener(SWT.MouseDown, new Listener() {
            @Override
            public void handleEvent(Event event) {
                selectText.run();
            }
        });
        shell.addListener(SWT.Activate, new Listener() {
            @Override
            public void handleEvent(Event event) {
                text.setFocus();
                selectText.run();
            }
        });

        return text;
    }

    private void translate(String w) {
        LinkedHashSet<String> trans = controller.getProvider().translate(w);
        updateTable(w, trans);
    }

    private void refreshColumnWidth() {
        table.getColumn(0).setWidth(shell.getBounds().width/2 - 24); //TODO do by layout
        table.getColumn(1).setWidth(shell.getBounds().width/2 - 23);
    }

    private void updateTable(String w, Collection<String> trans) {
        word = w;
        translations = trans.toArray(new String[0]);
        table.setItemCount(translations.length);
        table.clearAll();
    }

    private void switchLanguages() {
        controller.getProvider().switchLanguages();
        setTexts();
    }

    private void setTexts() {
        table.getColumn(0).setText(FROM + SPACE + controller.getProvider().getFromLang().toString());
        table.getColumn(1).setText(TO + SPACE + controller.getProvider().getToLang().toString());
    }

    /**
     * loop until disposed
     * Insert action event handlers here.
     */
    private void waitForEvents() {
        shell.open();
        while(!shell.isDisposed()) {
            if(!shell.getDisplay().readAndDispatch()) {
                shell.getDisplay().sleep();
            }
        }
    }

    public void dispose() {
        shell.dispose();
    }

    public void setVisible(boolean visible) {
        shell.setVisible(visible);
    }

    public void show() {
        waitForEvents();
    }

}
